#!/bin/sh 


. /usr/voltaire/common.sh


auto_ident=1
verbose=0
nogb=0

#Mellnox args
#-------------
MLX_Manufac_id="001"
Board_type_LP="001"
Board_type_PCI_exp="002"
Board_type_PCI_exp_MF="003"
Board_type_PCI_exp_DDR="004"
Board_type_PCI_exp_MF_DDR="005"
Board_type_PCI_exp_RevC="006"
Board_type_PCI_exp_MF_ARBEL="010"
Board_type_PCI_exp_MF_ARBEL_DDR="011"
LP_fw=/usr/voltaire/fw/HCA400-MLX_LP-23108-3_5_0.img
PCI_exp_fw=/usr/voltaire/fw/HCA400Ex-25208-4_8_2.img
PCI_exp_DDR_fw=/usr/voltaire/fw/HCA400Ex-D-25208-4_8_2.img
PCI_exp_revC_fw=/usr/voltaire/fw/HCA400Ex-rC-25208-4_8_2.img
PCI_exp_MF_fw=/usr/voltaire/fw/HCA410Ex-25204-1_2_0.img
PCI_exp_MF_DDR_fw=/usr/voltaire/fw/HCA410Ex-D-25204-1_2_0.img
PCI_exp_MF_ARBEL_fw=/usr/voltaire/fw/HCA400Ex-M-25218-5_2_0.img
PCI_exp_MF_ARBEL_DDR_fw=/usr/voltaire/fw/HCA400Ex-D-M-25218-5_2_0.img

#Sanmina args
#-----------
Sanmina_Manufac_id="002"
Sanmina_fw=/usr/voltaire/fw/HCA400-SANMINA-23108-3_5_0.img

#IBM blades HCA's args
#-----------
VLT_Manufac_id="003"
PCI_exp_BC_MF_fw=/usr/voltaire/fw/BC-HSEC-128-SDR-Rev1-25208-4_7_600.img
PCI_exp_BC_MFD_fw=/usr/voltaire/fw/BC-HSEC-128-DDR-Rev1-25208-4_7_600.img
Board_type_PCI_exp_BC_SDR="007"
Board_type_PCI_exp_BC_DDR="009"

# HP blades args
 HP_Manufac_id="HP"
 HP_001_fw=/usr/voltaire/fw/hpmezz-1.1.0.bin
 HP_003_fw=/usr/voltaire/fw/HCA400-MLX_LP-23108-3_5_0.img
 HP_004_fw=/usr/voltaire/fw/HCA400-MLX_LP-23108-3_5_0.img
 HP_005_fw=/usr/voltaire/fw/HCA400Ex-rC-25208-4_7_6.img
 HP_006_fw=/usr/voltaire/fw/HCA400Ex-D-25208-4_7_6.img
 HP_007_fw=/usr/voltaire/fw/HCA410Ex-D-25204-1_2_0.img
 HP_008_fw=/usr/voltaire/fw/HCA410Ex-25204-1_2_0.img

HP_Board_type_Mezzanine="001"
HP_Board_type_LP_3="003"
HP_Board_type_LP_4="004"
HP_Board_type_PCI_exp_RevC="005"
HP_Board_type_PCI_exp_DDR="006"
HP_Board_type_PCI_exp_MF_DDR="007"
HP_Board_type_PCI_exp_MF="008"
# ============================================================


GridBootVer="GBv"

function strstr ()
{
    # if s2 points to a string of zero length, strstr echoes s1
    [ ${#2} -eq 0 ] && { echo "$1" ; return 0; }

    # strstr echoes nothing if s2 does not occur in s1
    case "$1" in
    *$2*) ;;
    *) return 1;;
    esac

    # use the pattern matching code to strip off the match and everything
    # following it
    first=${1/$2*/}

    # then strip off the first unmatched portion of the string
    echo "${1##$first}"
}


function indentify_hca(){

	if [ $verbose -ne 0 ] ; then
		mstflint -d $HCA_DEV q
	fi
#	********************* ib-brun BUG **********************************************
#	The redirection to null is a bug or wrong way to change the script - Moshek "
#	VSD=$( mstflint -d $HCA_DEV q |grep -i board | awk   '{ print $3  }' >/dev/null)
#  
#       it simply delete the effect of all the following lines ->
#
#	VSD_first_char=$( echo $VSD | awk '{ print substr($0,1,1) }' )
#
#	if [ "$VSD_first_char" == "(" ]; then
#		VSD2=$VSD
#	else
#		VSD1=$VSD
#       This is the only line that is left and do the work  - Moshek
#
#	fi
#       ********************* ib-brun BUG End - Moshek ********************************

	VSD2=$( mstflint -d $HCA_DEV q |grep -i board | awk '{ print  $4 }')
	VSD_HP=$(echo $VSD2 | awk '{ print substr($0,2,2) }')
	VSD2_Board_type=$( echo $VSD2 | awk '{ print substr($0,5,3) }')
	if [ "$VSD_HP" == "HP" ]; then
		VSD2_Manufacture=$VSD_HP
	else
		VSD2_Manufacture=$( echo $VSD2 | awk '{ print substr($0,8,3) }' )
		VSD2_reserve=$( echo $VSD2 | awk '{ print substr($0,11,4) }' )
	fi

	if [ -e $VSD2_Manufacture ]; then
		fatal "Bad HCA identification. VPD-VSD is not burned"
	fi

	case "${VSD2_Manufacture}" in 
		"$MLX_Manufac_id") 
			case "${VSD2_Board_type}" in
			    "$Board_type_LP")
				   FW_IMAGE=$LP_fw
				   VSD_EXT=" -vsd1 VLT-LP  -vsd2 VLT$Board_type_LP$MLX_Manufac_id$VSD2_reserve "
				    ;;
			    "$Board_type_PCI_exp")
				    FW_IMAGE=$PCI_exp_fw
				    VSD_EXT=" -vsd1 VLT-EXP -vsd2 VLT$Board_type_PCI_exp$MLX_Manufac_id$VSD2_reserve "
				    ;;
			    "$Board_type_PCI_exp_MF")
				    FW_IMAGE=$PCI_exp_MF_fw
				    VSD_EXT=" -vsd1 VLT-MF -vsd2 VLT$Board_type_PCI_exp_MF$MLX_Manufac_id$VSD2_reserve "
				    ;;
			    "$Board_type_PCI_exp_RevC")
				    FW_IMAGE=$PCI_exp_revC_fw
				    VSD_EXT=" -vsd1 VLT-EXP-C -vsd2 VLT$Board_type_PCI_exp_RevC$MLX_Manufac_id$VSD2_reserve "
				    ;;
			    "$Board_type_PCI_exp_DDR")
				    FW_IMAGE=$PCI_exp_DDR_fw
				    VSD_EXT=" -vsd1 VLT-EXPD -vsd2 VLT$Board_type_PCI_exp_DDR$MLX_Manufac_id$VSD2_reserve "
				    ;;
			    "$Board_type_PCI_exp_MF_DDR")
				    FW_IMAGE=$PCI_exp_MF_DDR_fw
				    VSD_EXT=" -vsd1 VLT-MFD -vsd2 VLT$Board_type_PCI_exp_MF_DDR$MLX_Manufac_id$VSD2_reserve "
				    ;;
			    "$Board_type_PCI_exp_MF_ARBEL")
				    FW_IMAGE=$PCI_exp_MF_ARBEL_fw
				    VSD_EXT=" -vsd1 VLT-AMF -vsd2 VLT$Board_type_PCI_exp_MF_ARBEL$MLX_Manufac_id$VSD2_reserve"
				    ;;
			    "$Board_type_PCI_exp_MF_ARBEL_DDR")
				    FW_IMAGE=$PCI_exp_MF_ARBEL_DDR_fw
                                    VSD_EXT=" -vsd1 VLT-AMFD -vsd2 VLT$Board_type_PCI_exp_MF_ARBEL_DDR$MLX_Manufac_id$VSD2_reserve"
				    ;; 
			    *)
				   fatal "Bad HCA identification. Unknow Board type $VSD2_Board_type"
				    ;;
			esac
			;;
		"$Sanmina_Manufac_id")
			FW_IMAGE=$Sanmina_fw
			VSD_EXT="-vsd1 VLT-SAN -vsd2 VLT0010020001"
			;;
		"$VLT_Manufac_id")
                        case "${VSD2_Board_type}" in
                            "$Board_type_PCI_exp_BC_SDR")
				   FW_IMAGE=$PCI_exp_BC_MF_fw
			           VSD_EXT="-vsd1 VLT-BC-MF  -vsd2 VLT$Board_type_PCI_exp_BC_SDR$VLT_Manufac_id$VSD2_reserve "
				   ;;
                            "$Board_type_PCI_exp_BC_DDR")
				   FW_IMAGE=$PCI_exp_BC_MFD_fw
			           VSD_EXT="-vsd1 VLT-BC-MFD -vsd2 VLT$Board_type_PCI_exp_BC_DDR$VLT_Manufac_id$VSD2_reserve "
				   ;;
			    *)
				   fatal "Bad HCA identification. Unknow Board type $VSD2_Board_type"
				    ;;
	                esac
			;;
		"$HP_Manufac_id")
			VSD_EXT="-psid HP_"$VSD2_Board_type"0000001 -use_image_ps"
			case "${VSD2_Board_type}" in
				"$HP_Board_type_Mezzanine")
					FW_IMAGE=$HP_001_fw
                        		;;
				"$HP_Board_type_LP_3")
					FW_IMAGE=$HP_003_fw
					;;
				"$HP_Board_type_LP_4")
					FW_IMAGE=$HP_004_fw
                        		;;
				"$HP_Board_type_PCI_exp_RevC")
					FW_IMAGE=$HP_005_fw
					;;
				"$HP_Board_type_PCI_exp_DDR")
					FW_IMAGE=$HP_006_fw
					;;
				"$HP_Board_type_PCI_exp_MF_DDR")
					FW_IMAGE=$HP_007_fw
					;;
				"$HP_Board_type_PCI_exp_MF")
					FW_IMAGE=$HP_008_fw
					;;
				*) fatal "Bad HCA identification. Unknow HP Board type HP_"$VSD2_Board_type"0000001"
			
		  	esac
                        ;;
		*)
			fatal "Bad HCA identification. Unknown manufacturer $VSD2_Manufacture "
			;;
	esac
}

function is_gb_hca(){
	
        DESC=$(mstflint -d $HCA_DEV dc | grep Description | awk -F"=" '{print $2}' )
         if [ -z $DESC ]; then
                fatal "HCA FW description not found. Failed to recognize current FW version. Try to run with -nogb."
        fi
        GB_STATUS=$(strstr $DESC $GridBootVer)
        if [ -z $GB_STATUS ]; then
			return 1
        else
			return 0
        fi

}

function select_hca(){

	hca_type=$1
	VSD2_reserve=0001
	case $hca_type in
		"VLT-SAN")
			FW_IMAGE=$Sanmina_fw
			VSD_EXT="-vsd1 VLT-SAN -vsd2 VLT0010020001"
			;;
		"VLT-LP")
			FW_IMAGE=$LP_fw
			VSD_EXT=" -vsd1 VLT-LP  -vsd2 VLT$Board_type_LP$MLX_Manufac_id$VSD2_reserve "
			;;
		"VLT-EXP")
			FW_IMAGE=$PCI_exp_fw
			VSD_EXT=" -vsd1 VLT-EXP -vsd2 VLT$Board_type_PCI_exp$MLX_Manufac_id$VSD2_reserve "
			;;
		"VLT-EXP-C")
			FW_IMAGE=$PCI_exp_revC_fw
			VSD_EXT=" -vsd1 VLT-EXP-C -vsd2 VLT$Board_type_PCI_exp_RevC$MLX_Manufac_id$VSD2_reserve "
			;;
		"VLT-MF")
		       FW_IMAGE=$PCI_exp_MF_fw
		       VSD_EXT=" -vsd1 VLT-MF -vsd2 VLT$Board_type_PCI_exp_MF$MLX_Manufac_id$VSD2_reserve "
			;;
		"VLT-EXPD")
			FW_IMAGE=$PCI_exp_DDR_fw
			VSD_EXT=" -vsd1 VLT-EXPD -vsd2 VLT$Board_type_PCI_exp_DDR$MLX_Manufac_id$VSD2_reserve "
			;;
		"VLT-MFD")
			FW_IMAGE=$PCI_exp_MF_DDR_fw
			VSD_EXT=" -vsd1 VLT-MFD -vsd2 VLT$Board_type_PCI_exp_MF_DDR$MLX_Manufac_id$VSD2_reserve "
			;;
                "VLT-BC-MF")
                        FW_IMAGE=$PCI_exp_BC_MF_fw
                        VSD_EXT="-vsd1 VLT-BC-MF  -vsd2 VLT$Board_type_PCI_exp_BC_SDR$VLT_Manufac_id$VSD2_reserve "
                        ;;
                "VLT-BC-MFD")
                        FW_IMAGE=$PCI_exp_BC_MFD_fw
                        VSD_EXT="-vsd1 VLT-BC-MFD -vsd2 VLT$Board_type_PCI_exp_BC_DDR$VLT_Manufac_id$VSD2_reserve "
                        ;;
		"HP_0010000001")
			FW_IMAGE=$HP_001_fw
			VSD_EXT="-psid HP_0010000001 -use_image_ps"		
			;;
		"VLT-AMF")
			FW_IMAGE=$PCI_exp_MF_ARBEL_fw
                        VSD_EXT=" -vsd1 VLT-AMF -vsd2 VLT$Board_type_PCI_exp_MF_ARBEL$MLX_Manufac_id$VSD2_reserve"
			;;
		"VLT-AMFD")
			FW_IMAGE=$PCI_exp_MF_ARBEL_DDR_fw
                        VSD_EXT=" -vsd1 VLT-AMFD -vsd2 VLT$Board_type_PCI_exp_MF_ARBEL_DDR$MLX_Manufac_id$VSD2_reserve"
			;;
		*)
			fatal "Unknown HCA type $hca_type"
			;;
	esac
}
function list_hcas(){
	becho -n VLT-SAN 
	echo -e "\t\tVLT0010020001\tHCA400"	
#	-----------------------------
	becho -n VLT-LP
	echo -e "\t\tVLT0010010001\tHCA400"	
#	-----------------------------
	becho -n VLT-EXP 
	echo -e "\t\tVLT0020010001\tHCA400-EX"	
#	-----------------------------
	becho -n VLT-EXP-C
	echo -e "\tVLT0060010001\tHCA400-EX-C"	
#	-----------------------------
	becho -n VLT-MF
	echo -e "\t\tVLT0030010001\tHCA410"	
#	-----------------------------
	becho -n VLT-EXPD
	echo -e "\tVLT0040010001\tHCA400-EX-D"	
#	-----------------------------
	becho -n VLT-MFD
	echo -e "\t\tVLT0050010001\tHCA410-D"	
#	-----------------------------
        becho -n VLT-BC-MF
        echo -e "\tVLT0070030001\tBC-HSEC-128-SDR"
#       -----------------------------
        becho -n VLT-BC-MFD
        echo -e "\tVLT0090030001\tBC-HSEC-128-DDR"
#       -----------------------------
	becho -n HP_0010000001
	echo -e "\tHP_0010000001\thpmezz"
#  	-------------------------------
	becho -n VLT-AMF
	echo -e "\t\tVLT0100010001\tHCA400Ex-M"
#       -------------------------------
	becho -n VLT-AMFD
	echo -e "\tVLT0110010001\tHCA400Ex-D-M"	
#       -------------------------------
}

function usage(){
	becho Usage: $(basename $1) [-i HCA_TYPE] [-y] [-d dev_id ] [-h] [-hh] [-nofs] [-nogb]

	echo "-i:  tell $(basename $1) the type of HCA instead of performing auto HCA detection"
	echo "-y:  answer yes to all questions (non-interactive mode)"
	echo "-d:  select the device id if more than one HCA is installed. dev_id should be an index from 1 to N_HCAS"
	echo "-a:  use alternative firmware image file. Use with care"
	echo "-h:  print this message and exit"
	echo "-hh:  print a list of supported HCAs and exit"
	echo "-nofs: burn with non failsafe method"
	echo "-nogb: assume that firmware on HCA is non GridBoot"
}

# ============================================================
# ============================================================


while [[ ! -z "$1" ]] ; do
        case $1 in
                -h)
			usage $0
			exit
                ;;
                -hh)
			list_hcas
			exit
                ;;
                -y)
			ANSWER_YES_BURN="-y"
                        shift
                ;;
                -a)
			ALT_IMG=$2
                        shift
                        shift
                ;;
                -d)
			dev_id=$2
                        shift
                        shift
                ;;
                -v)
			verbose=1
                        shift
                ;;
                -f)
			FAKE=echo
                        shift
                ;;
                -i)
			hca_id=$2
                        shift
                        shift
                ;;
                -nogb)
                        nogb=1
                        shift
                ;;
                -nofs)
                        NOFS_FLAG="-nofs"
                        shift
                ;;

                *)
                        echo "Unknown option $1"
                        exit
                ;;
        esac
done


HCA_DEV=$(lspci -n|grep 15b3|grep -v 5a46|cut -f1 -d" "); 
if [ -z "$HCA_DEV" ] ; then
	fatal "HCA not present or not detected"
fi

N_HCAS=$(echo $HCA_DEV|wc -w)

if [ $N_HCAS -gt 1 ] ; then
	if [ -z $dev_id ] ; then
		info_red "$N_HCAS HCAs were detected. Please use -d <dev_index> to select one of them"
		exit 0
	else
		if [ $dev_id -gt $(($N_HCAS)) ] ; then
			info_red "illegal device index. should be in the range 1-$(($N_HCAS))"
			exit 0
		fi
		if [ $dev_id -lt 1 ] ; then
			info_red "illegal device index. should be in the range 1-$(($N_HCAS))"
			exit 0
		fi

		HCA_DEV=$(echo $HCA_DEV|cut -f$dev_id -d" ")
	fi
fi
if [ -z $hca_id ] ; then
	indentify_hca	
else
	select_hca $hca_id
fi

if [ ! -z $ALT_IMG ] ; then
	if [ -f $ALT_IMG ] ; then
		info "Using alternative image file $ALT_IMG"
		if [ -z $ANSWER_YES_BURN ] ; then
			get_yn Are you sure?
			if [ $yn = n ] ; then
				exit 1
			fi
		fi
		FW_IMAGE=$ALT_IMG
	else
		fatal " no such file $ALT_IMG"
	fi
fi
# make sure we dont override GridBoot HCA
if [ $nogb -eq 0 ] ; then
	is_gb_hca
	if [ $? -eq 0 ] ; then
		info "HCA is burned with GridBoot firmware." 
		if [ -z $ANSWER_YES_BURN ] ; then
			get_yn Do you want to overwrite?
			if [ $yn = n ] ; then
				exit 1
			fi
		fi
	fi
fi
echo Burning :  using fw image file: $FW_IMAGE   VSD extention : $VSD_EXT
$FAKE mstflint -d $HCA_DEV -i $FW_IMAGE  $VSD_EXT  $NOFS_FLAG  $ANSWER_YES_BURN burn
if [ $? -ne 0 ] ; then
	info "If you have problems with burning firmware"
	info "try to use the option -nofs for ib-burn"
fi
